import requests
import json
import logging
from datetime import datetime, timedelta
from flask import current_app

logger = logging.getLogger(__name__)

class GeolocationService:
    """地理位置服务类，用于获取IP地址的地理位置信息"""
    
    def __init__(self):
        """初始化地理位置服务"""
        self.cache = {}
        self.cache_expiry = timedelta(hours=24)  # 缓存24小时
    
    def _is_cache_valid(self, ip_address):
        """检查缓存是否有效"""
        if ip_address not in self.cache:
            return False
        
        cache_time = self.cache[ip_address].get('timestamp')
        if not cache_time:
            return False
        
        cache_time = datetime.fromisoformat(cache_time)
        now = datetime.now()
        
        return (now - cache_time) < self.cache_expiry
    
    def get_location_info(self, ip_address):
        """
        获取IP地址的地理位置信息
        
        Args:
            ip_address: IP地址
            
        Returns:
            dict: 地理位置信息
        """
        # 检查是否是本地或私有IP地址
        if ip_address in ['127.0.0.1', 'localhost'] or ip_address.startswith(('192.168.', '10.', '172.16.')):
            return {
                'country': 'Local',
                'city': 'Local',
                'region': 'Local',
                'timezone': 'Local'
            }
        
        # 检查缓存
        if self._is_cache_valid(ip_address):
            return self.cache[ip_address].get('geo_info')
        
        # 尝试多个地理位置API，提高成功率
        geo_services = [
            {
                'name': 'ipapi.co',
                'url': f'https://ipapi.co/{ip_address}/json/',
                'extract': lambda data: {
                    'country': data.get('country_name'),
                    'country_code': data.get('country_code'),
                    'city': data.get('city'),
                    'region': data.get('region'),
                    'timezone': data.get('timezone')
                }
            },
            {
                'name': 'ipinfo.io',
                'url': f'https://ipinfo.io/{ip_address}/json',
                'extract': lambda data: {
                    'country': data.get('country'),
                    'country_code': data.get('country'),
                    'city': data.get('city'),
                    'region': data.get('region'),
                    'timezone': data.get('timezone')
                }
            },
            {
                'name': 'extreme-ip-lookup.com',
                'url': f'https://extreme-ip-lookup.com/json/{ip_address}',
                'extract': lambda data: {
                    'country': data.get('country'),
                    'country_code': data.get('countryCode'),
                    'city': data.get('city'),
                    'region': data.get('region'),
                    'timezone': data.get('timezone')
                }
            },
            {
                'name': 'ipgeolocation.io',
                'url': f'https://api.ipgeolocation.io/ipgeo?apiKey=d87293ecfbe048c7b99e069c4108bff2&ip={ip_address}',
                'extract': lambda data: {
                    'country': data.get('country_name'),
                    'country_code': data.get('country_code2'),
                    'city': data.get('city'),
                    'region': data.get('state_prov'),
                    'timezone': data.get('time_zone', {}).get('name')
                }
            }
        ]
        
        # 依次尝试各个服务
        for service in geo_services:
            try:
                logger.info(f"尝试地理定位服务: {service['name']} 查询IP: {ip_address}")
                response = requests.get(service['url'], timeout=5)
                
                if response.ok:
                    data = response.json()
                    geo_info = service['extract'](data)
                    
                    # 确保所有值不为None
                    for key in geo_info:
                        if geo_info[key] is None:
                            geo_info[key] = 'Unknown'
                    
                    logger.info(f"地理定位成功: {service['name']} 返回国家: {geo_info.get('country')}")
                    
                    # 缓存结果
                    self.cache[ip_address] = {
                        'geo_info': geo_info,
                        'timestamp': datetime.now().isoformat()
                    }
                    
                    return geo_info
            except Exception as e:
                logger.error(f"地理定位服务 {service['name']} 失败: {str(e)}")
                # 忽略错误，继续尝试下一个服务
        
        logger.warning(f"所有地理定位服务均失败，无法获取IP {ip_address} 的地理信息")
        return {
            'country': 'Unknown',
            'city': 'Unknown',
            'region': 'Unknown',
            'timezone': 'Unknown'
        } 